#include <iostream>
using namespace std;

#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <json-c/json.h>
#include "stdShared.h"

#define SERVER_PORT 8888
#define SIZE        20
#define BUFFERSIZE 256

/* 为了保存对应的账号和信息，应该打包发送 */
struct userInfo
{
    int type;   //1表示注册，2表示登录
    char name[SIZE];
    char passwd[SIZE];
};

void *handleClientInfo(void * arg)
{
    /* 线程分离 */
    pthread_detach(pthread_self());
    
    int connfd = *(int *)arg;

    char readBuffer[BUFFERSIZE] = {0};
    memset(readBuffer, 0, sizeof(readBuffer));
    int readBytes = 0;
    
    while(1)
    {
        memset(readBuffer, 0, sizeof(readBuffer));
        readBytes = read(connfd, readBuffer, sizeof(readBuffer));
        if(readBytes < 0)
        {
            perror("read error:");
            break;
        }
        else if(readBytes == 0)
        {
            /* 客户端断开连接 */
            cout << "客户端断开连接!" <<endl;
            break;
        }
        else
        {
            cout  << "readBytes = "<< readBytes << " buffer = "<< readBuffer << endl;
            
            /* 1.将json字符串解析为json对象 */
            json_object * jsonObj = json_tokener_parse(readBuffer);

            /* 2.根据key得到value */
            #if 0
            json_object * typeVal =  json_object_object_get(jsonObj, "type");
            cout << "type : " << json_object_get_int64(typeVal) << endl;
            #endif
            int type = json_object_get_int(json_object_object_get(jsonObj, "type"));
            // const char * name = json_object_get_string(json_object_object_get(jsonObj, "name"));
            // const char * passwd = json_object_get_string(json_object_object_get(jsonObj, "passwd"));
            const char * musicName = json_object_get_string(json_object_object_get(jsonObj, "musicName"));

            if(type == REGISTER)
            {
                cout << "注册..." << type << endl;
                // cout << "username:" << name << endl;
                // cout << "passwd:" << passwd << endl;
            }
            else if(type == LOGIN)
            {
                cout << "登录..." << type << endl;
                // cout << "username:" << name << endl;
                // cout << "passwd:" << passwd << endl;
            }
            else if(type == DOWNLOAD_MUSIC)
            {
                cout << "下载..." << endl;
                cout << "musicName:" << musicName << endl;
            }
        }
        
    }
    /* 回收资源:不回收的话会浪费资源，文件描述符最大是1024 */
    close(connfd);

    pthread_exit(NULL);

}

int main()
{

    

    /* 创建套接字 */
    int sockfd =  socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1)
    {
        perror("sockfd error:");
        exit(-1);
    }
    cout << "sockfd = " << sockfd << endl;

    /* 设置端口复用，当先结束server时候，由于四次挥手的timewait，server会持续占用端口，2分钟之后才会断开 */
    int optVal = 1;
    int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
    if(ret != 0)
    {
        perror("setsockopt error");
        exit(-1);
    }

    while(1)
    {

        /* 绑定IP和端口信息 */
        struct sockaddr_in localAddress;
        /* 清空结构体的脏数据 */
        memset(&localAddress, 0, sizeof(localAddress));
        /* 地址族设置为IPV4 */
        localAddress.sin_family = AF_INET;
        /* 把主机字节序转为网络 */
        localAddress.sin_port = htons(SERVER_PORT);
        /* 设置全通规则 */
        localAddress.sin_addr.s_addr = htonl(INADDR_ANY);

        bind(sockfd, reinterpret_cast<struct sockaddr*>(&localAddress), sizeof(localAddress));

        /* 设置监听 */
        listen(sockfd, 0);


        cout << "等待连接..." << endl;

        /* 通信句柄 */
        /* 阻塞函数 */
         while(1)
        {
            int connfd = accept(sockfd, NULL, NULL);
            cout << "正在连接..." << connfd << endl;

            

            /* 给客户端创建独立的线程 */
            pthread_t tid;
            int ret = pthread_create(&tid, NULL, handleClientInfo, &connfd);
            if(ret != 0)
            {
                perror("thread create error:");
                exit(-1);
            }

            sleep(1);       //防止栈空间的局部变量被立马销毁

            #if 0
            userInfo info;
            memset(readBuffer, 0, sizeof(info));
            while(1)
            {
                /* 从客户端读取数据 */
                readBytes = read(connfd, &info, sizeof(info));
                if(readBytes < 0)
                {
                    cout << "readBytes < 0" <<endl;
                    break;
                }
                else if((readBytes == 0) || (strcmp(readBuffer, "exit") == 0))
                {
                    /* 客户端断开连接 */
                    cout << "客户端断开连接!" <<endl;
                    break;
                }
                else
                {
                    //cout  << "readBytes = "<< readBytes << " buffer = "<< readBuffer << endl;
                    // 将小写的英文字母转换为大写的英文字符
                    //for(int idx = 0; idx < readBytes; idx++)
                    // {
                    //     readBuffer[idx] = toupper(readBuffer[idx]);
                    // }

                    /* 分离出username和passwd */
                    cout << "type:" << info.type << endl;
                    cout << "username:" << info.name << endl;
                    cout << "passwd:" << info.passwd << endl;

                    /* 将数据写回客户端 */
                    write(connfd, readBuffer,readBytes);
                }
            }
            #endif
        }
    }
    close(sockfd); 

    return 0;
}